programming4us
           
 
 
Programming

iPhone 3D Programming : Vertices and Touch Points - Creating a Wireframe Viewer (part 1)

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
11/23/2010 11:51:29 AM
Let’s use vertex buffer objects and the touchscreen to create a fun new app. Instead of relying on triangles like we’ve been doing so far, we’ll use GL_LINES Figure 1. The rotation in Touch Cone was restricted to the plane, but this app will let you spin the geometry topology to create a simple wireframe viewer, as shown in around to any orientation; behind the scenes, we’ll use quaternions to achieve a trackball-like effect. Additionally, we’ll include a row of buttons along the bottom of the screen to allow the user to switch between different shapes. They won’t be true buttons in the UIKit sense; remember, for best performance, you should let OpenGL do all the rendering. This application will provide a good foundation upon which to learn many OpenGL concepts.
Figure 1. Wireframe viewer


If you’re planning on following along with the code, you’ll first need to start with the WireframeSkeleton project from this book’s example code (available at http://oreilly.com/catalog/9780596804831). In the Finder, make a copy of the directory that contains this project, and name the new directory SimpleWireframe. Next, open the project (it will still be named WireframeSkeleton), and then choose ProjectRename. Rename it to SimpleWireframe.

This skeleton project includes all the building blocks you saw (the vector library from the appendix, the GLView class, and the application delegate). There are a few differences between this and the previous examples, so be sure to look over the classes in the project before you proceed:

  1. The application delegate has been renamed to have a very generic name, AppDelegate.

  2. The GLView class uses an application engine rather than a rendering engine. This is because we’ll be taking a new approach to how we factor the ES 1.1– and ES 2.0–specific code from the rest of the project; more on this shortly.

1. Parametric Surfaces for Fun

You might have been put off by all the work required for tessellating the cone shape in the previous samples. It would be painful if you had to figure out a clever tessellation for every shape that pops into your head! Thankfully, most 3D modeling software can export to a format that has post-tessellated content; the popular .obj file format is one example of this. Moreover, the cone shape happens to be a mathematically defined shape called a parametric surface; all parametric surfaces are relatively easy to tessellate in a generic manner. A parametric surface is defined with a function that takes a 2D vector for input and produces a 3D vector as output. This turns out to be especially convenient because the input vectors can also be used as texture coordinates.

The input to a parametric function is said to be in its domain, while the output is said to be in its range. Since all parametric surfaces can be used to generate OpenGL vertices in a consistent manner, it makes sense to create a simple class hierarchy for them. Example 1 shows two subclasses: a cone and a sphere. This has been included in the WireframeSkeleton project for your convenience, so there is no need for you to add it here.

Example 1. ParametricEquations.hpp
#include "ParametricSurface.hpp"

class Cone : public ParametricSurface {
public:
Cone(float height, float radius) : m_height(height), m_radius(radius)
{
ParametricInterval interval = { ivec2(20, 20), vec2(TwoPi, 1) };
SetInterval(interval);
}
vec3 Evaluate(const vec2& domain) const
{
float u = domain.x, v = domain.y;
float x = m_radius * (1 - v) * cos(u);
float y = m_height * (v - 0.5f);
float z = m_radius * (1 - v) * -sin(u);
return vec3(x, y, z);
}
private:
float m_height;
float m_radius;
};

class Sphere : public ParametricSurface {
public:
Sphere(float radius) : m_radius(radius)
{
ParametricInterval interval = { ivec2(20, 20), vec2(Pi, TwoPi) };
SetInterval(interval);
}
vec3 Evaluate(const vec2& domain) const
{
float u = domain.x, v = domain.y;
float x = m_radius * sin(u) * cos(v);
float y = m_radius * cos(u);
float z = m_radius * -sin(u) * sin(v);
return vec3(x, y, z);
}
private:
float m_radius;
};

// ...


The classes in Example 1 request their desired tessellation granularity and domain bound by calling SetInterval from their constructors. More importantly, these classes implement the pure virtual Evaluate method, which simply applies Cone parameterization or Sphere parameterization.

Cone parameterization


Sphere parameterization


Each of the previous equations is only one of several possible parameterizations for their respective shapes. For example, the z equation for the sphere could be negated, and it would still describe a sphere.

In addition to the cone and sphere, the wireframe viewer allows the user to see four other interesting parametric surfaces: a torus, a knot, a Möbius strip,[3] and a Klein bottle (see Figure 2). I’ve already shown you the classes for the sphere and cone. They basically do nothing more than evaluate various well-known parametric equations. Perhaps more interesting is their common base class, shown in Example 2. To add this file to Xcode, right-click the Classes folder, choose AddNew file, select C and C++, and choose Header File. Call it ParametricSurface.hpp, and replace everything in it with the code shown here.

[3] True Möbius strips are one-sided surfaces and can cause complications with the lighting algorithms presented in the next chapter. The wireframe viewer actually renders a somewhat flattened Möbius “tube.”

Figure 2. Parametric gallery


Example 2. ParametricSurface.hpp
#include "Interfaces.hpp"

struct ParametricInterval {
ivec2 Divisions;
vec2 UpperBound;
};

class ParametricSurface : public ISurface {
public:
int GetVertexCount() const;
int GetLineIndexCount() const;
void GenerateVertices(vector<float>& vertices) const;
void GenerateLineIndices(vector<unsigned short>& indices) const;
protected:
void SetInterval(const ParametricInterval& interval);
virtual vec3 Evaluate(const vec2& domain) const = 0;
private:
vec2 ComputeDomain(float i, float j) const;
vec2 m_upperBound;
ivec2 m_slices;
ivec2 m_divisions;
};

I’ll explain the ISurface interface later; first let’s take a look at various elements that are controlled by subclasses:

Example 3 shows the implementation of the ParametricSurface class. Add a new C++ file to your Xcode project called ParametricSurface.cpp (but deselect the option to create the associated header file). Replace everything in it with the code shown.

Example 3. ParametricSurface.cpp
#include "ParametricSurface.hpp"

void ParametricSurface::SetInterval(const ParametricInterval& interval)
{
m_upperBound = interval.UpperBound;
m_divisions = interval.Divisions;
m_slices = m_divisions - ivec2(1, 1);
}

int ParametricSurface::GetVertexCount() const
{
return m_divisions.x * m_divisions.y;
}

int ParametricSurface::GetLineIndexCount() const
{
return 4 * m_slices.x * m_slices.y;
}

vec2 ParametricSurface::ComputeDomain(float x, float y) const
{
return vec2(x * m_upperBound.x / m_slices.x,
y * m_upperBound.y / m_slices.y);
}

void ParametricSurface::GenerateVertices(vector<float>& vertices) const
{
vertices.resize(GetVertexCount() * 3);
vec3* position = (vec3*) &vertices[0];
for (int j = 0; j < m_divisions.y; j++) {
for (int i = 0; i < m_divisions.x; i++) {
vec2 domain = ComputeDomain(i, j);
vec3 range = Evaluate(domain);
*position++ = range;
}
}
}

void ParametricSurface::GenerateLineIndices(vector<unsigned short>& indices) const
{
indices.resize(GetLineIndexCount());
vector<unsigned short>::iterator index = indices.begin();
for (int j = 0, vertex = 0; j < m_slices.y; j++) {
for (int i = 0; i < m_slices.x; i++) {
int next = (i + 1) % m_divisions.x;
*index++ = vertex + i;
*index++ = vertex + next;
*index++ = vertex + i;
*index++ = vertex + i + m_divisions.x;
}
vertex += m_divisions.x;
}
}



The GenerateLineIndices method deserves a bit of an explanation. Picture a globe of the earth and how it has lines for latitude and longitude. The first two indices in the loop correspond to a latitudinal line segment; the latter two correspond to a longitudinal line segment (see Figure 3). Also note some sneaky usage of the modulo operator for wrapping back to zero when closing a loop.

Figure 3. Generating line indices for a parametric surface


Other -----------------
- iPhone 3D Programming : Vertices and Touch Points - Boosting Performance with Vertex Buffer Objects
- iPhone 3D Programming : Vertices and Touch Points - Saving Memory with Vertex Indexing
- iPhone 3D Programming : Vertices and Touch Points - Reading the Touchscreen
- iPhone 3D Programming : HelloCone with Shaders
- Search Engine Basics : Country-Specific Search Engines
- Search Engine Basics : Vertical Search Engines
- Building Android Apps : Animation - Adding the Settings Panel
- Building Android Apps : Animation - Adding the New Entry Panel
- Building Android Apps : Animation - Adding the Date Panel
- Building Android Apps : Animation - Adding the Dates Panel
- Building Android Apps : Animation - Sliding Home
- Programming Windows Azure : Understanding the Value of Queues
- Programming Windows Azure : Table Operations - Deleting Tables, Deleting Entities
- Programming Windows Azure : Table Operations - Updating Entities
- Programming Windows Azure : Table Operations - Understanding Pagination
- Programming Windows Azure : Table Operations - Using Partitioning
- Programming Windows Azure : Table Operations - Querying Data
- Programming Windows Azure : Table Operations - Creating Entities
- Programming Windows Azure : Table Operations - Creating Tables
- iPad Development : Document Management (part 2)
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us